package com.tonyodev.fetchapp;

import ohos.aafwk.ability.Ability;
import ohos.agp.colors.RgbColor;
import ohos.agp.components.AttrHelper;
import ohos.agp.components.BaseItemProvider;
import ohos.agp.components.Button;
import ohos.agp.components.Component;
import ohos.agp.components.ComponentContainer;
import ohos.agp.components.DirectionalLayout;
import ohos.agp.components.LayoutScatter;
import ohos.agp.components.ProgressBar;
import ohos.agp.components.Text;
import ohos.agp.components.element.ShapeElement;
import ohos.agp.utils.Color;
import ohos.agp.utils.LayoutAlignment;
import ohos.agp.utils.Point;
import ohos.agp.utils.TextAlignment;
import ohos.agp.window.dialog.CommonDialog;
import ohos.agp.window.dialog.DisplayDialog;
import ohos.agp.window.dialog.ToastDialog;
import ohos.agp.window.service.Display;
import ohos.agp.window.service.DisplayManager;
import ohos.app.Context;
import ohos.utils.net.Uri;

import com.tonyodev.fetch2.Download;
import com.tonyodev.fetch2.Status;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

/**
 * xinglu
 *
 * @since 2021-04-22
 */
public class FileProvider extends BaseItemProvider {
    private final List<DownloadData> downloads = new ArrayList<>();
    private Ability ability;
    private ActionListener actionListener;

    //    /**
//     * 构造函数
//     *
//     * @param ability
//     */
    public FileProvider(Ability ability, ActionListener actionListener) {
        this.ability = ability;
        this.actionListener = actionListener;
    }


    @Override
    public int getCount() {
        return downloads == null ? 0 : downloads.size();
    }

    @Override
    public Object getItem(int position) {
        if (downloads != null && position >= 0 && position < downloads.size()) {
            return downloads.get(position);
        }
        return "";
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public Component getComponent(int position, Component convertComponent, ComponentContainer componentContainer) {
        final Component cpt;
        if (convertComponent == null) {
            cpt = LayoutScatter.getInstance(ability).parse(ResourceTable.Layout_down_item, null, false);
        } else {
            cpt = convertComponent;
        }


        bindView(cpt, position);
        return cpt;
    }

    private void bindView(Component cpt, int position) {
        DownloadData downloadData = downloads.get(position);
        Text titleTextView = (Text) cpt.findComponentById(ResourceTable.Id_titleTextView);
        ProgressBar progressBar = (ProgressBar) cpt.findComponentById(ResourceTable.Id_progressBar);
        Button actionButton = (Button) cpt.findComponentById(ResourceTable.Id_actionButton);
        Text progressTextView = (Text) cpt.findComponentById(ResourceTable.Id_progress_TextView);
        Text downloadedBytesPerSecondTextView = (Text) cpt.findComponentById(ResourceTable.Id_downloadSpeedTextView);
        Text timeRemainingTextView = (Text) cpt.findComponentById(ResourceTable.Id_remaining_TextView);
        Text statusTextView = (Text) cpt.findComponentById(ResourceTable.Id_status_TextView);


        actionButton.setClickedListener(null);
        actionButton.setEnabled(true);

        String url = "";
        if (downloadData.download != null) {
            url = downloadData.download.getUrl();
        }
        final Uri uri = Uri.parse(url);
        final Status status = downloadData.download.getStatus();
        final Context context = cpt.getContext();


        titleTextView.setText(uri.getLastPath());
        statusTextView.setText(getStatusString(status));

        int progress = downloadData.download.getProgress();
        if (progress == -1) { // Download progress is undermined at the moment.
            progress = 0;
        }
        progressBar.setProgressValue(progress);
        progressTextView.setText(ability.getString(ResourceTable.String_percent_progress, progress));

        if (downloadData.eta == -1) {
            timeRemainingTextView.setText("");
        } else {
            timeRemainingTextView.setText(Utils.getETAString(context, downloadData.eta));
        }

        if (downloadData.downloadedBytesPerSecond == 0) {
            downloadedBytesPerSecondTextView.setText("");
        } else {
            downloadedBytesPerSecondTextView.setText(Utils.getDownloadSpeedString(context, downloadData.downloadedBytesPerSecond));
        }

        switch (status) {
            case COMPLETED: {
                actionButton.setText(ResourceTable.String_view);
                actionButton.setClickedListener(view -> {
                    showCustomText(ability.getContext(), "Downloaded Path:" + downloadData.download.getFile());
                });
                break;
            }
            case FAILED: {
                actionButton.setText(ResourceTable.String_retry);
                actionButton.setClickedListener(view -> {
                    actionButton.setEnabled(false);
                    actionListener.onRetryDownload(downloadData.download.getId());
                });
                break;
            }
            case PAUSED: {
                actionButton.setText(ResourceTable.String_resume);
                actionButton.setClickedListener(view -> {
                    actionButton.setEnabled(false);
                    actionListener.onResumeDownload(downloadData.download.getId());
                });
                break;
            }
            case DOWNLOADING:
            case QUEUED: {
                actionButton.setText(ResourceTable.String_pause);
                actionButton.setClickedListener(view -> {
                    actionButton.setEnabled(false);
                    actionListener.onPauseDownload(downloadData.download.getId());
                });
                break;
            }
            case ADDED: {
                actionButton.setText(ResourceTable.String_download);
                actionButton.setClickedListener(view -> {
                    actionButton.setEnabled(false);
                    actionListener.onResumeDownload(downloadData.download.getId());
                });
                break;
            }
            default: {
                break;
            }
        }

        cpt.setLongClickedListener(v -> {
            final Uri uri12 = Uri.parse(downloadData.download.getUrl());

            CommonDialog commonDialog = new CommonDialog(cpt.getContext());
            Component component = LayoutScatter.getInstance(cpt.getContext()).parse(ResourceTable.Layout_fileprovider_item_dialog, null, true);
            Text title = (Text) component.findComponentById(ResourceTable.Id_title);
            Text cancel = (Text) component.findComponentById(ResourceTable.Id_cancel);
            Text delete = (Text) component.findComponentById(ResourceTable.Id_delete);
            Optional<Display> defaultDisplay = DisplayManager.getInstance().getDefaultDisplay(context);
            Point point = new Point();
            defaultDisplay.get().getSize(point);
            int width = defaultDisplay.get().getAttributes().width;
            commonDialog.setSize((int) (width * 0.85f), AttrHelper.vp2px(125, context));
            commonDialog.setContentCustomComponent(component);
            commonDialog.setAutoClosable(true);
            title.setText(ability.getContext().getString(ResourceTable.String_delete_title) + uri12.getLastPath());

            cancel.setClickedListener(new Component.ClickedListener() {
                @Override
                public void onClick(Component component) {
                    commonDialog.hide();
                }
            });

            delete.setClickedListener(new Component.ClickedListener() {
                @Override
                public void onClick(Component component) {
                    actionListener.onRemoveDownload(downloadData.download.getId());
                    commonDialog.hide();
                }
            });

            commonDialog.show();

        });


    }


    public void addDownload(final Download download) {
        boolean found = false;
        DownloadData data = null;
        int dataPosition = -1;
        for (int i = 0; i < downloads.size(); i++) {
            final DownloadData downloadData = downloads.get(i);
            if (downloadData.id == download.getId()) {
                data = downloadData;
                dataPosition = i;
                found = true;
                break;
            }
        }
        if (!found) {
            final DownloadData downloadData = new DownloadData();
            downloadData.id = download.getId();
            downloadData.download = download;
            downloads.add(downloadData);
            notifyDataSetItemInserted(downloads.size() - 1);
        } else {
            data.download = download;
            notifyDataSetItemChanged(dataPosition);
        }
    }

    public void update(final Download download, long eta, long downloadedBytesPerSecond) {
        for (int position = 0; position < downloads.size(); position++) {
            final DownloadData downloadData = downloads.get(position);
            if (downloadData.id == download.getId()) {
                switch (download.getStatus()) {
                    case REMOVED:
                    case DELETED: {
                        downloads.remove(position);
                        notifyDataChanged();
//                        notifyDataSetItemRemoved(position);
                        break;
                    }
                    default: {
                        downloadData.download = download;
                        downloadData.eta = eta;
                        downloadData.downloadedBytesPerSecond = downloadedBytesPerSecond;
                        notifyDataSetItemChanged(position);
                    }
                }
                return;
            }
        }
    }

    private String getStatusString(Status status) {
        switch (status) {
            case COMPLETED:
                return "Done";
            case DOWNLOADING:
                return "Downloading";
            case FAILED:
                return "Error";
            case PAUSED:
                return "Paused";
            case QUEUED:
                return "Waiting in Queue";
            case REMOVED:
                return "Removed";
            case NONE:
                return "Not Queued";
            default:
                return "Unknown";
        }
    }


    public static class DownloadData {
        public int id;
        public Download download;
        long eta = -1;
        long downloadedBytesPerSecond = 0;

        @Override
        public int hashCode() {
            return id;
        }

        @Override
        public String toString() {
            if (download == null) {
                return "";
            }
            return download.toString();
        }

        @Override
        public boolean equals(Object obj) {
            return obj == this || obj instanceof DownloadData && ((DownloadData) obj).id == id;
        }
    }


    public static void showCustomText(Context context, String toastStr) {
        Text textComponent = new Text(context);
        textComponent.setText(toastStr);
        int padding = AttrHelper.fp2px(20, context);
        //设置间距为10vp
        //int left, int top, int right, int bottom
        textComponent.setPadding(10, 10, 10, 10);
//        textComponent.setMarginLeft(10);
        textComponent.setTextColor(Color.WHITE);
        textComponent.setTextAlignment(TextAlignment.CENTER);
        textComponent.setTextSize(AttrHelper.fp2px(12, context));
        ShapeElement shapeElement = new ShapeElement();
        //  shapeElement.setShape(ShapeElement.RECTANGLE);
        //设置背景半透明
        shapeElement.setRgbColor(RgbColor.fromArgbInt(Color.rgb(108, 118, 124)));
        shapeElement.setCornerRadius(AttrHelper.fp2px(30, context));
        textComponent.setBackground(shapeElement);
        //设置文字允许多行
        textComponent.setMultipleLine(true);

        DirectionalLayout.LayoutConfig layoutConfig = new DirectionalLayout.LayoutConfig();
        layoutConfig.width = ComponentContainer.LayoutConfig.MATCH_CONTENT;
        layoutConfig.height = ComponentContainer.LayoutConfig.MATCH_CONTENT;
        layoutConfig.alignment = LayoutAlignment.CENTER;
        textComponent.setLayoutConfig(layoutConfig);

        ToastDialog toastDialog = new ToastDialog(context).setDuration(1000).setComponent(textComponent).setAlignment(LayoutAlignment.BOTTOM);
        //设置弹框背景透明
        toastDialog.setOffset(0, 50);
        toastDialog.setTransparent(true);
        toastDialog.show();
    }
}
